package com.derbysoft.dswitch.adapter.ihg.dswitch2.translate;

import com.derbysoft.dswitch.adapter.ihg.common.utils.CloneUtils;
import com.derbysoft.dswitch.adapter.ihg.dswitch3.translate.Translator;
import com.derbysoft.dswitch.adapter.ihg.dto.AvailRoomStay;
import com.derbysoft.dswitch.adapter.ihg.dto.OTAHotelAvailRQ;
import com.derbysoft.dswitch.adapter.ihg.dto.OTAHotelAvailRS;
import com.derbysoft.dswitch.adapter.ihg.dto.RoomRate;
import com.derbysoft.dswitch.adapter.ihg.webservice.impl.ResponsePair;
import com.derbysoft.remote.dswitch.core.GenericRQ;
import com.derbysoft.remote.dswitch.core.GenericRS;
import com.derbysoft.remote.dswitch.core.ResponseHeader;
import com.derbysoft.remote.dswitch.core.SuccessDTO;
import com.derbysoft.remote.dswitch.generic.dto.UniqueIDDTO;
import com.derbysoft.remote.dswitch.hotel.dto.*;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component("ds2HotelMultiAvailRSTranslatorV2")
public class HotelMultiAvailRSTranslatorV2 extends BaseTranslator
        implements Translator<List<ResponsePair<OTAHotelAvailRQ, OTAHotelAvailRS>>, GenericRS<HotelMultiAvailRS>, GenericRQ<HotelMultiAvailRQ>> {
    @Override
    public GenericRS<HotelMultiAvailRS> translate(List<ResponsePair<OTAHotelAvailRQ, OTAHotelAvailRS>> availResponsePairs,
                                                  GenericRQ<HotelMultiAvailRQ> hotelMultiAvailRQ) {
        GenericRS<HotelMultiAvailRS> hotelMutiAvailRS = new GenericRS<HotelMultiAvailRS>();
        hotelMutiAvailRS.setHeader(translateResponseHeader(hotelMultiAvailRQ));
        hotelMutiAvailRS.setSuccess(new SuccessDTO());
        HotelMultiAvailRS payLoad = new HotelMultiAvailRS();
        payLoad.setHotelAvailRoomStays(translateHotelAvailRoomStays(availResponsePairs, hotelMultiAvailRQ));
        hotelMutiAvailRS.setPayload(payLoad);
        return hotelMutiAvailRS;
    }

    private List<HotelAvailRoomStayDTO> translateHotelAvailRoomStays(List<ResponsePair<OTAHotelAvailRQ, OTAHotelAvailRS>> availResponsePairs,
                                                                     GenericRQ<HotelMultiAvailRQ> hotelMultiAvailRQ) {
        List<HotelAvailRoomStayDTO> hotelAvailRoomStays = new ArrayList<HotelAvailRoomStayDTO>();
        for (ResponsePair<OTAHotelAvailRQ, OTAHotelAvailRS> availResponsePair : availResponsePairs) {
            AvailRoomStay roomStay = availResponsePair.getResponse().getRoomStays().getRoomStay().get(0);
            hotelAvailRoomStays.add(translateHotelAvailRoomStay(roomStay, availResponsePair, hotelMultiAvailRQ.getPayload()));
        }
        setProviderChain(hotelAvailRoomStays, hotelMultiAvailRQ);
        return hotelAvailRoomStays;
    }

    private void setProviderChain(List<HotelAvailRoomStayDTO> hotelAvailRoomStays, GenericRQ<HotelMultiAvailRQ> hotelMultiAvailRQ) {
        UniqueIDDTO chainID = CloneUtils.clone(hotelMultiAvailRQ.getHeader().getDestinations().get(0).getUniqueID());
        for (HotelAvailRoomStayDTO hotelAvailRoomStay : hotelAvailRoomStays) {
            for (AvailRoomStayDTO availRoomStayDTO : hotelAvailRoomStay.getRoomStays()) {
                availRoomStayDTO.setProviderChain(translateProviderChain(chainID));
            }
        }
    }

    private HotelAvailRoomStayDTO translateHotelAvailRoomStay(AvailRoomStay roomStay,
                                                              ResponsePair<OTAHotelAvailRQ, OTAHotelAvailRS> availResponsePair,
                                                              HotelMultiAvailRQ hotelMultiAvailRQ) {
        HotelAvailRoomStayDTO hotelAvailRoomStayDTO = new HotelAvailRoomStayDTO();
        hotelAvailRoomStayDTO.setHotelRef(new HotelRefDTO(availResponsePair.getRequest().getHotelPassport()));
        hotelAvailRoomStayDTO.setRoomStays(translateRoomStays(roomStay, hotelMultiAvailRQ));
        return hotelAvailRoomStayDTO;
    }

    private List<AvailRoomStayDTO> translateRoomStays(AvailRoomStay roomStay, HotelMultiAvailRQ hotelMultiAvailRQ) {
        List<AvailRoomStayDTO> availRoomStays = new ArrayList<AvailRoomStayDTO>();
        StayDateRangeDTO stayDateRange = hotelMultiAvailRQ.getStayDateRange();
        for (RoomRate roomRate : roomStay.getRoomRates().getRoomRate()) {
            com.derbysoft.dswitch.adapter.ihg.common.domain.RatePlan ratePlan = ratePlanRepository.loadByCode(roomRate.getRatePlanCode());
            if (ratePlan == null) {
                continue;
            }
            availRoomStays.add(translateAvailRoomStay(roomRate, roomStay, ratePlan, stayDateRange));
        }
        return availRoomStays;
    }

    private ResponseHeader translateResponseHeader(GenericRQ<HotelMultiAvailRQ> hotelMultiAvailRQ) {
        ResponseHeader responseHeader = new ResponseHeader();
        responseHeader.setTaskId(hotelMultiAvailRQ.getHeader().getTaskId());
        return responseHeader;
    }
}
